<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        /*
          只要可以定义函数的地方都可以定义生成器 
          箭头函数不能定义生成器
         */

        function* generatorFn() {}

        let foo = {
            * generatorFn() {}
        }

        class Foo {
            * generatorFn() {}
        }

        // 作为静态类
        class Bar {
            static * generatorFn() {}
        }

        /*
          调用一个生成器函数会产生一个生成器对象。
          生成器对象开始处于暂停状态(suspended)。
          生成器函数实现了Iterator接口，因此也有next()方法，调用这个方法让生成器开始或恢复执行 
         */
        function *generatorFn1() {}
        const g = generatorFn1()
        console.log(g)  // generatorFn1  [[GeneratorState]]: "suspended"
        console.log(g.next) // ƒ next() { [native code] }
        console.log(g.next())  // {value: undefined, done: true}

        // next()返回值的value属性是生成器的返回值，默认undefined
        function *generatorFn2() {
            return 'xiaomi'
        }
        console.log(generatorFn2().next()) // {value: 'xiaomi', done: true}

        // 单纯调用generatorFu3()并不会执行函数体(不会有打印输出)
        // 只用在调用next()方法后才会执行
        function *generatorFn3() {
            console.log('xiaomi')
        }
        generatorFn3()
        generatorFn3().next() // xiaomi

        /*
           生成器实现了Iterable接口, 它们默认的迭代器是自引用
         */
        function *generatorFn4() {}
        console.log(generatorFn4) // ƒ *generatorFn4() {}
        console.log(generatorFn4()[Symbol.iterator]) // ƒ [Symbol.iterator]() { [native code] }
        console.log(generatorFn4())  // generatorFn4 {<suspended>}
        console.log(generatorFn4()[Symbol.iterator]())  // generatorFn4 {<suspended>}
        const g4 = generatorFn4()
        console.log(g4 === g4[Symbol.iterator]()) // true
    </script>
</body>
</html>